#include "vec3.h"

namespace TG
{
	const vec3 vec3::up			= vec3(0, 1, 0);
	const vec3 vec3::down		= vec3(0, -1, 0);
	const vec3 vec3::left		= vec3(-1, 0, 0);
	const vec3 vec3::right		= vec3(1, 0, 0);
	const vec3 vec3::forward	= vec3(0, 0, 1);
	const vec3 vec3::back		= vec3(0, 0, -1);

	float vec3::magnitude() const
	{
		return sqrt(x * x + y * y + z * z);
	}

	vec3& vec3::normalize()
	{
		float len = magnitude();
		x = x / len;
		y = y / len;
		z = z / len;
		return *this;
	}

	vec3::operator vec4()
	{
		return vec4(x, y, z, 1);
	}

	vec3 operator-(const vec3 &v0, const vec3 &v1)
	{
		return vec3(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z);
	}

	vec3 operator+(const vec3 &v0, const vec3 &v1)
	{
		return vec3(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z);
	}

	vec3 operator*(const vec3 &v0, const vec3 &v1)
	{
		return vec3(v0.x * v1.x, v0.y * v1.y, v0.z * v1.z);
	}

	vec3 operator*(const vec3 &v0, float s)
	{
		return vec3(v0.x * s, v0.y * s, v0.z * s);
	}

	vec3 operator*(float s, const vec3 &v0)
	{
		return vec3(v0.x * s, v0.y * s, v0.z * s);
	}

	vec3 operator/(const vec3 &v0, float &&s)
	{
		return vec3(v0.x / s, v0.y / s, v0.z / s);
	}

	vec3 normalize(const vec3 &v0)
	{
		float len = v0.magnitude();
		return vec3(v0.x / len, v0.y / len, v0.z / len);
	}

	vec3 cross(const vec3 &v0, const vec3 &v1)
	{
		return vec3(v0.y*v1.z - v0.z * v1.y, v0.z * v1.x - v0.x * v1.z, v0.x * v1.y - v0.y * v1.x);
	}

	float dot(const vec3 &v0, const vec3 &v1)
	{
		return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
	}
}